package cn.itmtr.document.download.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.ZipUtil;
import cn.itmtr.document.download.common.exception.ItmtrException;
import cn.itmtr.document.download.common.util.HtmlDownloadUtil;
import cn.itmtr.document.download.common.util.TdEnvBeanUtil;
import cn.itmtr.document.download.common.util.UrlProperty;
import cn.itmtr.document.download.common.validator.Assert;
import cn.itmtr.document.download.mapper.DocumentMapper;
import cn.itmtr.document.download.model.entity.Document;
import cn.itmtr.document.download.service.IDocumentService;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author mtr
 * @since 2021-10-04
 */
@Service
public class DocumentServiceImpl extends ServiceImpl<DocumentMapper, Document> implements IDocumentService {

    @Override
    public Document createDocument(String documentName, String url) {
        Assert.isBlank(documentName, "文档名称不可为空");
        Assert.isBlank(url, "文档链接不可为空");
        Assert.isTrue(!ReUtil.isMatch(RegexPool.URL_HTTP, url), "请输入正确格式的网址");
        Document document = new Document();
        document.setDocumentName(documentName);
        document.setUrl(url);
        UrlProperty urlProperty = HtmlDownloadUtil.resolveUrl(url);
        document.setProtocol(urlProperty.getProtocol());
        document.setDomain(urlProperty.getDomain());
        document.setRootPath(TdEnvBeanUtil.getProjectJarPath() + "/" + documentName);
        document.setStatus(0);
        document.setGmtCreate(DateUtil.now());
        document.setGmtUpdate(DateUtil.now());
        this.save(document);
        return document;
    }

    @Override
    public void updateStatus(Integer id, Integer status) {
        this.update(
                new UpdateWrapper<Document>()
                        .set("status", status)
                        .set("gmt_update", DateUtil.now())
                        .eq("id", id)
        );
    }

    @Override
    public void downloadDocument(Document document, HttpServletResponse response, String userAgent) {
        File docZipFile = ZipUtil.zip(document.getRootPath(), document.getRootPath() + ".zip", true);
        try {
            // 设置 header
            setDownloadableHeader(response, userAgent, docZipFile.getName());
            // 下载文件
            OutputStream stream = response.getOutputStream();
            FileReader reader = new FileReader(docZipFile.getAbsolutePath());
            reader.writeToStream(stream);
            stream.flush();
            stream.close();
        } catch (Exception e) {
            log.error("下载文件 " + docZipFile.getName() + " 失败", e);
            throw new ItmtrException("文件下载失败");
        }
    }

    /**
     * 设置下载头部
     *
     * @param response  response
     * @param userAgent UA
     * @param fileName  文件名称
     * @author mtr
     * @date 2021/10/5
     */
    private void setDownloadableHeader(HttpServletResponse response, String userAgent, String fileName) throws UnsupportedEncodingException {
        String busiSuccess = "true";
        response.setCharacterEncoding("UTF-8");
        if (userAgent.toLowerCase().indexOf("firefox") > 0) {
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");
        } else if (userAgent.toUpperCase().indexOf("MSIE") > 0) {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } else if (userAgent.toUpperCase().indexOf("CHROME") > 0
                || userAgent.toUpperCase().indexOf("SAFARI") > 0) {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        }
        response.reset();
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "online; filename=\"" + fileName + "\"");
        response.setHeader("Connetion", "close");
        Cookie fileDownloadCookie = new Cookie("fileDownload", busiSuccess);
        fileDownloadCookie.setPath("/");
        response.addCookie(fileDownloadCookie);
    }

    @Override
    public void removeFile(Document document) {
        try {
            FileUtil.del(document.getRootPath());
            FileUtil.del(document.getRootPath() + ".zip");
        } catch (Exception e) {
            log.error("删除文件失败", e);
        }
    }

}
